﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Titan
{
    [DataContract]
    public class PropertyExpression:IPropertyExpression
    {
         #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public PropertyExpression()
        {
            GroupFunction = GroupFunction.None;
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="propertyName">输出属性的名称</param>
        /// <param name="orderType">排序类型</param>
        public PropertyExpression(string propertyName)
        {
            PropertyName = propertyName;
            GroupFunction = GroupFunction.None;
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="propertyName">输出属性的名称</param>
        /// <param name="orderType">排序类型</param>
        public PropertyExpression(string propertyName, GroupFunction groupFunction)
        {
            PropertyName = propertyName;
            GroupFunction = groupFunction;
        }

        #endregion

        /// <summary>
        /// 输出的属性的名称
        /// </summary> 
        [DataMember]
        public string PropertyName { get; set; }



        /// <summary>
        /// 排序类型，升序或者降序
        /// </summary> 
        [DataMember]
        public GroupFunction GroupFunction { get; set; }

        #region 快速条件
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem Custom(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.Custom, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem Equal(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.Equal, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem GreaterThanOrEqual(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.GreaterThanOrEqual, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem GreaterThan(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.GreaterThan, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem In(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.In, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem LessThanOrEqual(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.LessThanOrEqual, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem LessThan(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.LessThan, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem Like(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.Like, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem NotEqual(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.NotEqual, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem NotIn(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.NotIn, value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem NotLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.NotLike, value);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem LeftLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.LeftLike, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem LeftNotLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.NotLeftLike, value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem RightLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.RightLike, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem RightNotLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.NotRightLike, value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem FullTextLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.FullTextLike, value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public ConditionItem FullTextNotLike(object value)
        {
            return new ConditionItem(this.PropertyName, this.GroupFunction, ConditionOperator.NotFullTextLike, value);
        }
        #endregion

        #region 快速代码
        //count只会有一个，所以用静态
        //private PropertyExpression count;
        public static PropertyExpression Count
        {
            get
            {
                return new PropertyExpression("***", GroupFunction.Count);
            }
        }
        private PropertyExpression sum;
        public PropertyExpression Sum
        {
            get
            {
                if ((object)sum == null) sum = new PropertyExpression(this.PropertyName, GroupFunction.Sum);
                return sum;
            }
        }
        private PropertyExpression avg;
        public PropertyExpression Avg
        {
            get
            {
                if ((object)avg == null) avg = new PropertyExpression(this.PropertyName, GroupFunction.Avg);
                return avg;
            }
        }
        private PropertyExpression max;
        public PropertyExpression Max
        {
            get
            {
                if ((object)max == null) max = new PropertyExpression(this.PropertyName, GroupFunction.Max);
                return max;
            }
        }
        private PropertyExpression min;
        public PropertyExpression Min
        {
            get
            {
                if ((object)min == null) min = new PropertyExpression(this.PropertyName, GroupFunction.Min);
                return min;
            }
        }

        private OrderExpression asc;
        public OrderExpression Asc
        {
            get
            {
                if (asc == null) asc = new OrderExpression(this.PropertyName,this.GroupFunction, OrderType.Asc);
                return asc;
            }
        }
        private OrderExpression desc;
        public OrderExpression Desc
        {
            get
            {
                if (desc == null) desc = new OrderExpression(this.PropertyName, this.GroupFunction, OrderType.Desc);
                return desc;
            }
        }
        #endregion

        #region 运算符重载
        public static ConditionItem operator ==(PropertyExpression left, object value)
        {
            return new ConditionItem(left.PropertyName,left.GroupFunction, ConditionOperator.Equal, value);
        }
        public static ConditionItem operator !=(PropertyExpression left, object value)
        {
            return new ConditionItem(left.PropertyName, left.GroupFunction, ConditionOperator.NotEqual, value);
        }
        public static ConditionItem operator >(PropertyExpression left, object value)
        {
            return new ConditionItem(left.PropertyName, left.GroupFunction, ConditionOperator.GreaterThan, value);
        }
        public static ConditionItem operator >=(PropertyExpression left, object value)
        {
            return new ConditionItem(left.PropertyName, left.GroupFunction, ConditionOperator.GreaterThanOrEqual, value);
        }
        public static ConditionItem operator <(PropertyExpression left, object value)
        {
            return new ConditionItem(left.PropertyName, left.GroupFunction, ConditionOperator.LessThan, value);
        }
        public static ConditionItem operator <=(PropertyExpression left, object value)
        {
            return new ConditionItem(left.PropertyName, left.GroupFunction, ConditionOperator.LessThanOrEqual, value);
        }


        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.PropertyName == null ? base.GetHashCode() : this.PropertyName.GetHashCode() ^ this.GroupFunction.GetHashCode();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return base.Equals(obj);
            }
            else
            {
                string thisString = this.ToString();
                string objString = obj.ToString();
                if (thisString == null)
                {
                    return objString == null;
                }
                else
                {
                    return thisString.Equals(objString);
                } 
            }
        }

        public override string ToString()
        {
            return GroupFunction == GroupFunction.None ? PropertyName : (GroupFunction.ToString() + "(" + PropertyName + ")");
        }
    }
}
